package com.ruoyi.project.mahjong.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.exception.BaseException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.redis.RedisCache;
import com.ruoyi.framework.web.domain.AjaxResult;
import com.ruoyi.project.mahjong.domain.*;
import com.ruoyi.project.mahjong.domain.dto.*;
import com.ruoyi.project.mahjong.domain.enu.*;
import com.ruoyi.project.mahjong.domain.uyil.MemberLogUtil;
import com.ruoyi.project.mahjong.domain.vo.DeskVo;
import com.ruoyi.project.mahjong.domain.vo.MemberOpenVo;
import com.ruoyi.project.mahjong.domain.vo.TOpenTableVo;
import com.ruoyi.project.mahjong.mapper.*;
import com.ruoyi.project.mahjong.service.ITCostService;
import com.ruoyi.project.mahjong.service.ITMemberLogService;
import com.ruoyi.project.mahjong.service.ITOpenTableService;
import com.ruoyi.project.mahjong.service.ITTablenumberService;
import com.ruoyi.project.remake.domain.enmu.YesORNoEnum;
import com.ruoyi.project.system.domain.SysDept;
import com.ruoyi.project.system.domain.SysUser;
import com.ruoyi.project.system.mapper.SysUserMapper;
import com.ruoyi.project.system.service.ISysDeptService;
import lombok.Synchronized;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * 新开桌Service业务层处理
 *
 * @author ruoyi
 * @date 2023-10-07
 */
@Service
public class TOpenTableServiceImpl implements ITOpenTableService {

    @Autowired
    private ISysDeptService sysDeptService;
    @Autowired
    private TOpenTableMapper tOpenTableMapper;
    @Autowired
    private TOutSendMapper tOutSendMapper;
    @Autowired
    private TMemberMapper tMemberMapper;
    @Autowired
    private ITCostService costService;
    @Autowired
    private TCostMapper tCostMapper;
    @Autowired
    private SysUserMapper userMapper;
    @Autowired
    private TRoomServiceImpl roomService;
    @Autowired
    private ITTablenumberService tableNumberService;
    @Autowired
    private TTablenumberMapper tTablenumberMapper;
    @Autowired
    private TRecordMapper recordMapper;
    @Autowired
    private TOpenMoneyMapper tOpenMoneyMapper;
    @Autowired
    private TIntegralMapper tIntegralMapper;
    @Autowired
    private ITMemberLogService tMemberLogService;
    @Autowired
    private RedisCache redisCache;
    @Autowired
    private DeskIngMapper deskIngMapper;
    @Autowired
    private MoneyCalculateServiceImpl calculateService;
    @Autowired
    private ITTablenumberService tablenumberService;

    /**
     * 查询新开桌
     *
     * @param id 新开桌ID
     * @return 新开桌
     */
    @Override
    public TOpenTable selectTOpenTableById(Long id) {
        return tOpenTableMapper.selectTOpenTableById(id);
    }

    /**
     * 查询新开桌列表
     *
     * @param tOpenTable 新开桌
     * @return 新开桌
     */
    @Override
    public List<TOpenTable> selectTOpenTableList(TOpenTable tOpenTable) {
        return tOpenTableMapper.selectTOpenTableList(tOpenTable);
    }

    /**
     * 新增新开桌
     *
     * @param tOpenTable 新开桌
     * @return 结果
     */
    @Override
    public int insertTOpenTable(TOpenTable tOpenTable) {
        tOpenTable.setCreateTime(DateUtils.getNowDate());
        return tOpenTableMapper.insertTOpenTable(tOpenTable);
    }

    /**
     * 修改新开桌
     *
     * @param tOpenTable 新开桌
     * @return 结果
     */
    @Override
    public int updateTOpenTable(TOpenTable tOpenTable) {
        tOpenTable.setUpdateTime(DateUtils.getNowDate());
        return tOpenTableMapper.updateTOpenTable(tOpenTable);
    }

    /**
     * 批量删除新开桌
     *
     * @param ids 需要删除的新开桌ID
     * @return 结果
     */
    @Override
    public int deleteTOpenTableByIds(Long[] ids) {
        return tOpenTableMapper.deleteTOpenTableByIds(ids);
    }

    /**
     * 删除新开桌信息
     *
     * @param id 新开桌ID
     * @return 结果
     */
    @Override
    public int deleteTOpenTableById(Long id) {

        return tOpenTableMapper.deleteTOpenTableById(id);
    }

    /**
     * 点击房间开桌按钮需要的数据
     *
     * @return
     */
    @Override
    public OpenTableDto getOpenVo(Long shopId, String roomId) {
        OpenTableDto openTableDto = new OpenTableDto();
        List<TMember> tMemberList = tMemberMapper.selectNoOpenTableTMemberList(shopId);
        if (tMemberList.isEmpty()) {
            throw new BaseException("暂无会员信息");
        }
        TCost tCost = new TCost();
        tCost.setBak1(roomId);
        tCost.setBak2(shopId.toString());
        List<TCost> tCostList = tCostMapper.selectCostName(shopId.toString(), roomId);

        if (tCostList.isEmpty()) {
            throw new BaseException("暂无计费模式");
        }
        openTableDto.setTMembers(tMemberList);
        openTableDto.setTCost(tCostList);
        return openTableDto;
    }

    /**
     * 首页所有房间数据
     *
     * @param shopId 店铺id
     *               bak1 :对应店铺id
     * @return
     */
    @Override
    public List<TRoom> getIndexDataVo(Long shopId) {
        TRoom tRoom = new TRoom();
        tRoom.setBak1(shopId.toString());
//       房间
        List<TRoom> tRooms = roomService.selectTRoomList(tRoom);
        if (ObjectUtil.isEmpty(tRooms)) {
            throw new BaseException("当前店铺暂无房间信息");
        }
        TTablenumber tTablenumber = new TTablenumber();
        tTablenumber.setBelong(shopId.toString());
//       查出此店铺所有桌子
        List<TTablenumber> tTablenumbers = tTablenumberMapper.selectTTablenumberList(tTablenumber);
        if (ObjectUtil.isEmpty(tTablenumbers)) {
            throw new BaseException("当前店铺暂无桌台信息");
        }

//        查出此店铺所有桌子开桌情况
        List<TOpenTable> openTables = tOpenTableMapper.selectTOpenTableListGroupByShopTableId(shopId);
//         查出每个桌子的商品消费金额,和占用时间 和 计费名称
        if (ObjectUtil.isNotEmpty(openTables)) {
            for (TOpenTable table : openTables) {
//          设置每个桌子的商品消费金额,和占用时间 和 计费名称
                TOpenTable table1 = getProductAndMoneyAndUseTimeAndCostName(table);
                table.setUseTime(table1.getUseTime());
                table.setProductCostMoney(table1.getProductCostMoney());
                table.setCostTypeName(table1.getCostTypeName());
            }
        }
        List<TOpenTable> op1 = new ArrayList<>();
        //       开桌开桌情况放进桌子信息
        for (TTablenumber tablenumber : tTablenumbers) {//桌子
            String tablenumberId = tablenumber.getId().toString();
            boolean flag = false;
            for (TOpenTable openTable : openTables) {//桌子开桌情况
                if (tablenumberId.equals(openTable.getTableId().toString())) {
                    if ("1".equals(openTable.getStatus())) {
                        tablenumber.settOpenTable(null);
                        break;
                    }
                    tablenumber.settOpenTable(openTable);
                    flag = true;
                    break;
                }
            }
            if (!flag) {
                if (tablenumber.getStatus().equals("3")) {
                    DeskIng deskIng = deskIngMapper.selectByOrderSn(tablenumber.getOrderSn());
                    TOpenTable openTable = new TOpenTable();
                    if (null == deskIng) {
                        tablenumber.settOpenTable(openTable);
                    } else {

                        Date time = ObjectUtil.isNotNull(deskIng.getStartTime()) ? deskIng.getStartTime() : new Date();
                        Long startTime = time.getTime();
                        openTable.setOpenTime(DateUtils.countOpenTableTime(startTime, null, false, false, false));
                        openTable.setBak2(deskIng.getOrderSn());
                        TCost cost = tCostMapper.selectTCostById(Long.valueOf(deskIng.getMode()));
                        openTable.setCostType(cost.getCostName());
                        openTable.setRemark(deskIng.getRemark());
                        openTable.setStopStatus(ObjectUtil.isNull(deskIng.getStatus()) ? "0" : deskIng.getStatus());
                        String useTime = countOpenTableTime(startTime, null, false, false, false);
                        openTable.setUseTime(useTime);
                        if ("1".equals(openTable.getStatus())) {
                            tablenumber.settOpenTable(null);
                        } else {
                            tablenumber.settOpenTable(openTable);
                        }

                    }
                }

            }
        }

//        桌子信息放进房间

        for (TRoom room : tRooms) {//房间
            List<TTablenumber> lists = new ArrayList<>();
            String roomId = room.getId().toString();
            for (TTablenumber tablenumber : tTablenumbers) {//桌子
                if (roomId.equals(tablenumber.getRoomType())) {
                    lists.add(tablenumber);
                    room.settTablenumbers(lists);
                }
            }

        }
        return tRooms;
    }


    /**
     * 查询每个桌子的消费类型,商品消费总数,使用时间
     * 需要参数:
     * 归属的店铺id
     * 此桌的会员id
     * 桌号id
     *
     * @param openTables
     * @return
     */
    private TOpenTable getProductAndMoneyAndUseTimeAndCostName(TOpenTable openTables) {
//         String shopId = openTables.getBak1();
//         Long tableId = openTables.getTableId();
////       去查此桌人员信息再查询每个会员消费情况
//         List <TMember> tMember =tMemberMapper.selectTMemberByShopIdAndTableId(shopId,tableId);
        Long startTime = DateUtils.parseDate(openTables.getOpenStartTime()).getTime();
        String useTime = countOpenTableTime(startTime, null, false, false, false);
        System.out.println(openTables.getTableId());
        System.out.println(openTables.getOpenStartTimes());

        openTables.setUseTime(useTime);//查询使用时间
        // 根据计费类型查询计费名称
        TCost tCost = tCostMapper.selectTCostByCostType(Long.valueOf(openTables.getCostType()));
        openTables.setCostTypeName(tCost.getCostName());
//       查询会员消费情况
        String orderNumber = openTables.getBak2();
        TOpenMoney tOpenMoney = new TOpenMoney();
        tOpenMoney.setOrderNumber(orderNumber);
        List<TOpenMoney> tOpenMonies = tOpenMoneyMapper.selectTOpenMoneyList(tOpenMoney);
        BigDecimal productCostMoney = new BigDecimal(0.0);
        for (TOpenMoney tOpenMony : tOpenMonies) {
            productCostMoney = tOpenMony.getMoney().add(productCostMoney);
        }
        openTables.setProductCostMoney(productCostMoney.toString());
        return openTables;
    }


    /**
     * 开桌操作
     * 1新增开桌数据
     * 2改变归属店铺的桌子状态
     * 3在流水表里记录操作此桌的员工和记录此桌归属的店铺
     *
     * @param openTableIng
     * @return
     */
    @Override
    @Transactional
    public String insertTOpenTableAndIdInfo(OpenTableIng openTableIng) {
        String orderNumber = orderMethod();
        //基本信息开桌
        String costType = openTableIng.getTOpenTable().getCostType();
        TCost tCost = tCostMapper.selectTCostByCostType(Long.valueOf(costType));
        tCost = getDeskCost(tCost);
        openTableIng.getTOpenTable().setCostType(tCost.getId().toString());
        initDeskIng(openTableIng, orderNumber);
        //初始化开桌详情
        List<Long> tMembers = openTableIng.getTMember();
        TOpenTable tOpenTable1 = openTableIng.getTOpenTable();
        tOpenTable1.setBak1(openTableIng.getShopId().toString());
        tOpenTable1.setStaffId(openTableIng.getStaffId().toString());
        tOpenTable1.setRemark(openTableIng.getTOpenTable().getRemark());


        if (ObjectUtil.isNotNull(openTableIng.getTOpenTable().getOpenStartTime())) {
            tOpenTable1.setOpenStartTime(openTableIng.getTOpenTable().getOpenStartTime());

        } else {
            tOpenTable1.setOpenStartTime(new Date().toString());
        }

        List<Long> memberIds = new ArrayList<>();
        for (Long ids : tMembers) {
            memberIds.add(ids);
            tOpenTable1.setMemberId(ids.toString());
            //tOpenTable1.setMemberName(member.getName());
            tOpenTable1.setBak2(orderNumber);
//      1新增开桌数据
            Integer insertStatus = tOpenTableMapper.insertTOpenTable(tOpenTable1);
            if (insertStatus == 0) {
                throw new BaseException("开桌失败，请重试");
            }
        }

        Long shopId = openTableIng.getShopId();

        if (ObjectUtil.isNotEmpty(memberIds) && memberIds.size() != 0) {
            //  改变会员开桌状态
            Integer i = tMemberMapper.updateMemberTableIng(shopId, memberIds);
        }

//

//      2改变归属店铺的桌子状态:根据店铺和房间改变桌子状态
        Long tableId = openTableIng.getTOpenTable().getTableId();
        Long roomId = openTableIng.getTOpenTable().getRoomId();
        String time = ObjectUtil.isNotNull(openTableIng.getTOpenTable().getOpenStartTime()) ? openTableIng.getTOpenTable().getOpenStartTime() : DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.getNowDate());
        int updateStatus = tTablenumberMapper.updateTableStatus(shopId, roomId, tableId, TablenumberState.START.getValue(), orderNumber, time);
        if (updateStatus == 0) {
            throw new BaseException("桌子使用错误，请重试");
        }

//      3在流水表里记录操作此桌的员工和记录此桌归属的店铺
//        List<TRecord> tRecords=new ArrayList<>();
//        String  jbid  = redisCache.getCacheObject(shopId+openTableIng.getStaffId().toString());
        Long jbid = redisCache.getCacheObject(shopId + openTableIng.getStaffId().toString());

        if (ObjectUtil.isNull(jbid)) {
            throw new RuntimeException("需要先交接上班！");
        }

//        int intergrals=0;
//        Double money1=0.0;
//        if (ObjectUtil.isNotNull(tCost)){
//            if (tCost.getCostId()==2l){//按分时段包段计费，桌台费用是死的，所以先把消费赠送积分先到流水里
//                 TIntegral tIntegral = tIntegralMapper.selectCostGiveIntegral(shopId);
//
//                intergrals = countGiveIntergrals(tIntegral, new BigDecimal(tCost.getMoney()));
//                if ( ObjectUtil.isNotNull(tCost.getMoney())){
//                      money1 = tCost.getMoney();
//                }
//            }
//        }else {
//            throw new BaseException("未查到该计费模式");
//        }

        List<Long> tMember = openTableIng.getTMember();
        Integer insertRecord = null;
        TRecord tRecord = new TRecord();
        for (Long member : tMember) {
            tRecord.setOrderNumber(orderNumber);
//        tRecord.setReceiveIntegrai(String.valueOf(intergrals));
            tRecord.setHandoverId(jbid.toString());
            tRecord.setStaffId(openTableIng.getStaffId());
            tRecord.setShopId(openTableIng.getShopId());
            tRecord.setIncomeProjectType(openTableIng.getTOpenTable().getRoomId().toString());
//      收入项目类型,是字典可能会增删改,所以这里注释掉,让员工选择收入项目类型字典
//      tRecord.setIncomeProjectType(openTableIng.getTOpenTable().getRoomType());
            tRecord.setCostTable(openTableIng.getTOpenTable().getTableId().toString());
            tRecord.setShopIncome(ShopIncomeType.INCOME.getValue());
            tRecord.setIsCheckout(CheckoutType.NO.getValue());
            tRecord.setCreateTime(new Date());
            tRecord.setCostMemberId(member);//消费会员

            //  tRecord.setCostMemberName(member.getName());//消费会员名称
            tRecord.setBak3(openTableIng.getTOpenTable().getRoomId().toString());
//        tRecords.add(tRecord);
            insertRecord = recordMapper.insertTRecord(tRecord);
//                    添加日志
       /*     for (Long ids : tMembers) {
                TMemberLog tMemberLog = MemberLogUtil.insertMemberLog(
                        shopId,
                        openTableIng.getStaffId(),
                        ids,
                        null,
                        null,
                        "进行开房",
                        orderNumber, null
                );
                tMemberLogService.insertTMemberLog(tMemberLog);
            }*/
            if (insertRecord == 0) {
                return "0";
            }
        }


        return orderNumber;
    }

    /**
     * 获取开桌的设定
     *
     * @param tCost
     * @return
     */
    private TCost getDeskCost(TCost tCost) {
        if (tCost.getCostId() == 2L) {
            //根据当前的时间获取对应的开局配置
            TCost myCost = new TCost();
            myCost.setBak1(tCost.getBak1());
            myCost.setBak2(tCost.getBak2());
            myCost.setCostId(tCost.getCostId());
            List<TCost> tCostList = tCostMapper.selectTCostList(myCost);
            for (TCost cost : tCostList) {
                String startTime = cost.getStartTime();//开始时间
                String endTime = cost.getEndTime();//
                Calendar calendar = Calendar.getInstance();
                calendar.set(Calendar.HOUR_OF_DAY, Integer.valueOf(startTime.split(":")[0]));
                calendar.set(Calendar.MINUTE, Integer.valueOf(startTime.split(":")[1]));
                Date statDate = calendar.getTime();
                calendar.set(Calendar.HOUR_OF_DAY, Integer.valueOf(endTime.split(":")[0]));
                calendar.set(Calendar.MINUTE, Integer.valueOf(endTime.split(":")[1]));
                Date endDate = calendar.getTime();
                Date timeNow = new Date();
                if (timeNow.getTime() > statDate.getTime() && timeNow.getTime() < endDate.getTime()) {
                    return cost;
                }
            }
        }
        return tCost;
    }

    /**
     * 打开基本的信息
     *
     * @param openTableIng
     */
    private void initDeskIng(OpenTableIng openTableIng, String orderSn) {
        DeskIng deskIng = new DeskIng();
        deskIng.setUserId(openTableIng.getStaffId());
        deskIng.setShopId(openTableIng.getShopId());
        deskIng.setDeskId(openTableIng.getTOpenTable().getTableId());
        deskIng.setRemark(openTableIng.getTOpenTable().getRemark());
        Date time = ObjectUtil.isNotEmpty(openTableIng.getTOpenTable().getOpenStartTime()) ? DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, openTableIng.getTOpenTable().getOpenStartTime()) : new Date();
        deskIng.setStartTime(time);
        //计费方式
        deskIng.setMode(openTableIng.getTOpenTable().getCostType());
        deskIng.setStatus(DeskStatusEnum.OK.getValue());
        deskIng.setOrderSn(orderSn);
        TTablenumber tTablenumber = tTablenumberMapper.selectTTablenumberById(openTableIng.getTOpenTable().getTableId());
        deskIng.setDeskNumber(Integer.valueOf(tTablenumber.getRoomType()));
        deskIngMapper.insertDeskIng(deskIng);
    }

    /**
     * 订单编号
     *
     * @return
     */
    public String orderMethod() {
        Random random = new Random();
        int i = random.nextInt(9000) + 1000;
        return String.valueOf(System.currentTimeMillis() + i);
    }

    /**
     * 查询开桌详情
     */
    @Override
    @Transactional
    public TOpenTableVo getOpenTableInfo(String orderNumber) {
        TOpenTableVo tOpenTableVo = new TOpenTableVo();
        /**
         * 获取开桌情况
         */
        DeskIng deskIng = deskIngMapper.selectByOrderSn(orderNumber);
        /**
         * 根据单号查询桌子开桌情况（会员列表信息）
         */
        TOpenTable openTable = new TOpenTable();
        openTable.setBak2(orderNumber);
        openTable.setIsDel("0");
        List<TOpenTable> tOpenTables = tOpenTableMapper.selectopenTableList(openTable);
        if (ObjectUtil.isNotEmpty(tOpenTables)) {
            TOpenTable openTable1 = tOpenTables.get(0);
            BeanUtil.copyProperties(openTable1, tOpenTableVo);
            /**
             * 桌号
             */
            TTablenumber tableNumber = tableNumberService.selectTTablenumberById(openTable1.getTableId());
            tOpenTableVo.setTableName(tableNumber.getTablenumberId());
            /**
             * 计费规则
             */
            TCost tCost = tCostMapper.selectTCostById(Long.valueOf(openTable1.getCostType()));
            tOpenTableVo.setCostName(tCost.getCostName());
            /**
             * 开桌时长
             */
            tOpenTableVo.setOpenTime(countOpenTableTime(DateUtils.parseDate(openTable1.getOpenStartTime()).getTime(), null, false, false, false));
            /**
             * 备注
             */

            tOpenTableVo.setRemark(deskIng.getRemark());
            /**
             * 本卓会员以及消费情况
             */
            List<MemberOpenVo> memberOpenVos = new ArrayList<>();
            List<TOpenMoney> openMoneyList = new ArrayList<>();
            for (TOpenTable tOpenTable : tOpenTables) {
                /**
                 * 获取会员余额
                 */
                TMember tMember = tMemberMapper.selectTMemberById(Long.valueOf(tOpenTable.getMemberId()));
                MemberOpenVo memberOpenVo = new MemberOpenVo();
                memberOpenVo.setId(Long.valueOf(tOpenTable.getMemberId()));
                memberOpenVo.setName(tOpenTable.getMemberName());
                memberOpenVo.setMoney(tMember.getMoney());
                memberOpenVo.setStatus(tOpenTable.getStatus());
                memberOpenVo.setOpenTableMoney(tOpenTable.getMoney());
                /**
                 * 根据订单号以及会员ID获取在此桌子的商品消费
                 */
                TOpenMoney tOpenMoney = new TOpenMoney();
                tOpenMoney.setOrderNumber(orderNumber);
                tOpenMoney.setMemberId(Long.valueOf(tOpenTable.getMemberId()));
                List<TOpenMoney> openMonies = tOpenMoneyMapper.selectTOpenMoneyList(tOpenMoney);
                BigDecimal totalBigDecimal = new BigDecimal("0.0");
                for (TOpenMoney openMoney : openMonies) {
                    openMoney.setMemberName(tOpenTable.getMemberName());
                    totalBigDecimal = totalBigDecimal.add(openMoney.getMoney());
                    openMoneyList.add(openMoney);
                }
                memberOpenVo.setProductMoney(totalBigDecimal);
                memberOpenVo.setConsumeMoney(tOpenTable.getMoney().add(totalBigDecimal));
                memberOpenVos.add(memberOpenVo);
            }
            tOpenTableVo.setMemberList(memberOpenVos);
            tOpenTableVo.setMemberBuyList(openMoneyList);





//            for (TOpenTable table : tOpenTables) {//把会员的消费情况也放进去
                // List<TOpenMoney> tOpenMonies = tOpenMoneyMapper.selectTOpenMoneyBymemberId(table.getMemberId(), orderNumber);
                // TMember member = tMemberMapper.selectTMemberById(Long.valueOf(table.getMemberId()));
//                TMember tMember1 = new TMember();
//                tMember1.setStoredMoney(member.getStoredMoney());
//                tMember1.setSendMoney(member.getSendMoney());
//                if (ObjectUtil.isNotEmpty(tOpenMonies)) {
//                    tMember1.setTOpenMoney(tOpenMonies);
//                    tMember1.setMemberId(table.getMemberId());
//                    tMember1.setName(table.getMemberName());
//
//                    tMember1.setStatus(table.getStatus());
//                    tMember1.setDeskAmount(table.getMoney());
//                    double money = tOpenMonies.stream().mapToDouble(obj -> obj.getMoney().doubleValue()).sum();
//                    tMember1.setMoney(new BigDecimal(money));
//                    memberList.add(tMember1);
//                } else {
//                    tMember1.setMemberId(table.getMemberId());
//                    tMember1.setName(table.getMemberName());
//                    tMember1.setStatus(table.getStatus());
//                    tMember1.setDeskAmount(table.getMoney());
//                    tMember1.setMoney(new BigDecimal(0));
//                    memberList.add(tMember1);
//                }
//            }


           /* if (tCost.getCostId() == 0l) {//计算费用按分钟计算
                money = countOpenTableCost(orderNumber, startTime);
            } else if (tCost.getCostId() == 1l) {//计算费用按包场计算计算
               *//* BigDecimal hour = new BigDecimal(tCost.getCostUnit());//每小时
                BigDecimal money1 = new BigDecimal(tCost.getMoney());//金额
                BigDecimal usrHmz = new BigDecimal(new Date().getTime()).subtract(new BigDecimal(startTime));
                BigDecimal usehour = usrHmz.divide(new BigDecimal(1000), 2, BigDecimal.ROUND_HALF_UP).divide(new BigDecimal(60), 2, BigDecimal.ROUND_HALF_UP).divide(new BigDecimal(60), 2, BigDecimal.ROUND_HALF_UP);
                int i = usehour.compareTo(hour);
                if (i == -1) {//小于hour，就直接当前金额
                    money = money.add(money1);
                } else {
                    BigDecimal bigDecimal = usehour.divide(hour, 2, BigDecimal.ROUND_HALF_UP);
                    BigDecimal useMoney = bigDecimal.multiply(money1).setScale(2, BigDecimal.ROUND_HALF_UP);
                    money = money.add(useMoney);
                }*//*
            } else if (tCost.getCostId() == 2l) {//按分时段包段计费
              *//*  String[] startTime1 = tCost.getStartTime().split(":");
                String[] endTime = tCost.getEndTime().split(":");
                Integer hour = Integer.valueOf(endTime[0]) - Integer.valueOf(startTime1[0]);
                BigDecimal money1 = new BigDecimal(tCost.getMoney());
                BigDecimal useHour = new BigDecimal(hour);
                money = money.add(useHour.multiply(money1));*//*
            } else {
                throw new BaseException("收费模式错误");
            }
            tOpenTableVo.setMoney(money);*/

//  找出每个会员和会员消费的商品金额加上桌子费用,如果消费金额大于会员余额则set断电状态
       /*     for (TMember member : tMember) {
                List<TOpenMoney> tOpenMoney = member.getTOpenMoney();
                BigDecimal productMoney = new BigDecimal(0.0);
                if (ObjectUtil.isNotEmpty(tOpenMoney)) {
                    for (TOpenMoney openMoney : tOpenMoney) {
                        productMoney = productMoney.add(openMoney.getMoney().setScale(2, BigDecimal.ROUND_HALF_UP));
                    }
                }
                member.setLingShiFeiYong(productMoney);
                if (member.getMoney().compareTo(money) == -1) {
                    tOpenTableVo.setAccountStatus("2");//保存余额不足断电记录
                    TOutSend tOutSend = new TOutSend();
                    tOutSend.setRoomId(tOpenTables.get(0).getRoomId().toString());
                    tOutSend.setTableId(tOpenTables.get(0).getTableId().toString());
                    tOutSend.setBak1("2");
                    tOutSend.setShopId(tCost.getBak2());
                    tOutSend.setBak2(member.getMemberId());
                    tOutSend.setSendTime(new Date());
                    tOutSend.setBak3(orderNumber);
                    tOutSendMapper.insertTOutSend(tOutSend);
                } else {
                    tOpenTableVo.setAccountStatus("1");
                }

            }*/
         /*   if (tCost.getCostId() == 2l) {
                String outFlag = countIsOutTime(orderNumber);
                //     计算出现错误
                if (outFlag.equals("0")) {
                    throw new BaseException("计算是否超时出现错误,请重试");
                }
                //        超时
                if (outFlag.equals("1")) {//保存超时断电记录
                    tOpenTableVo.setOutTime("2");
                    TOutSend tOutSend = new TOutSend();
                    tOutSend.setShopId(tCost.getBak2());
                    tOutSend.setRoomId(tOpenTables.get(0).getRoomId().toString());
                    tOutSend.setTableId(tOpenTables.get(0).getTableId().toString());
                    tOutSend.setBak1("1");
                    tOutSend.setSendTime(new Date());
                    tOutSend.setBak3(orderNumber);
                    tOutSendMapper.insertTOutSend(tOutSend);
                } else {
                    tOpenTableVo.setOutTime("1");
                }
//        是否达到超时提醒
                if (outFlag.equals("2")) {
                    tOpenTableVo.setIsRemind(true);
                } else {
                    tOpenTableVo.setIsRemind(false);
                }
            }*/
        } else {
            tOpenTableVo = coverData(orderNumber);
        }
        return tOpenTableVo;
    }

    /**
     * 停止计费
     *
     * @param orderNumber
     * @return
     */
    @Override
    public void tableStopBilling(String orderNumber) {
        tOpenTableMapper.updateTableStatus(orderNumber,DeskStatusEnum.NO.getValue());
        // 桌子断电
        DeskIng deskIng = deskIngMapper.selectByOrderSn(orderNumber);
        tablenumberService.closeEnergize(deskIng.getDeskId());
    }

    /**
     * 如果没有会员信息，则进行转化
     *
     * @param orderNumber
     * @return
     */
    private TOpenTableVo coverData(String orderNumber) {
        DeskIng deskIng = deskIngMapper.selectByOrderSn(orderNumber);
        TTablenumber tTablenumber = tTablenumberMapper.selectTTablenumberById(deskIng.getDeskId());
        TOpenTableVo tOpenTableVo = new TOpenTableVo();
        Long time = DateUtils.getNowDate().getTime() - deskIng.getStartTime().getTime();
        tOpenTableVo.setOpenStartTime(deskIng.getStartTime());
        tOpenTableVo.setOpenTime(DateUtils.countOpenTableTime(deskIng.getStartTime().getTime(), null, false, false, false));
        tOpenTableVo.setRemark(deskIng.getRemark());
        TCost tCost = tCostMapper.selectTCostById(Long.valueOf(deskIng.getMode()));
        tOpenTableVo.setStopStatus(ObjectUtil.isNull(deskIng.getStatus()) ? "1" : "0");
        tOpenTableVo.setBak2(orderNumber);
        tOpenTableVo.setTableName(tTablenumber.getTablenumberId());
        tOpenTableVo.setCostName(ObjectUtil.isNotNull(tCost) ? tCost.getCostName() : "");
        return tOpenTableVo;
    }

    /**
     * 计算每个人的开桌费用
     *
     * @param table
     * @return
     */
    private BigDecimal countDeskAmonut(TOpenTable table) {
        return new BigDecimal(100);
    }


    /**
     * 查询是否超时,超时转下场
     * 计算是否达到超时，或者是否达到超时提醒。返回值 -1不需要超时或者超时提醒  1超时 2超时提醒  0则计算出现错误
     * 1 获取当前使用时间,
     * 2查询超时转下场数据进行计算,
     * 3如果转下场则先把当前场费用保存下来,并重置时间
     *
     * @param orderNumber
     * @return
     */
    private String countIsOutTime(String orderNumber) {
       /* TOpenTable openTable = tOpenTableMapper.selectTOpenTableByOrderNumber(orderNumber);
        TCost tCost = tCostMapper.selectTCostByCostType(Long.valueOf(openTable.getCostType()));
//        String status = tCost.getOutTimeStatus();//1开启，2关闭
        Long costUnit = Long.valueOf(tCost.getCostUnit());
        if (costUnit <= 1) {
            return "-1";
        }

//        计算是否达到超时
//        if (status.equals("1")){//开启超时转下场了
        int i = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
        if (Integer.valueOf(tCost.getEndTime()) > i) {   //超时
            return "1";
        }

//        }*/
        return "0";
    }

    /**
     * 结束开桌 确认结账 待做：结账时计算费用  待做会员消费计算
     * 传给我： 应收金额 ,实收金额 ，订单编号 ,此时操作的员工id
     * 我需要： 1根据订单编号找到桌子改变桌子状态
     * 2查询此桌费用和会员消费情况计算
     * 3查询当局所有会员消费情况去计算费用并扣除余额并计算赠送积分
     * 4根据订单编号找到流水记录修改流水状态
     * 5删除开桌中表中和开桌中商品消费表的记录
     * 6改变会员个人开桌状态
     *
     * @param
     * @return
     */
    @Override
    @Transactional
    public String overOpenTable(OverOpenTableDto Dto) {
        Long jbid = redisCache.getCacheObject(Dto.getShopId() + Dto.getStaffId().toString());

//        1根据订单编号找到桌子恢复桌子状态
        String orderNumber = Dto.getOrderNumber();
        TOpenTable tOpenTable = new TOpenTable();
        tOpenTable.setBak2(orderNumber);
        List<TOpenTable> openTables = tOpenTableMapper.selectTOpenTableList(tOpenTable);
        if (ObjectUtil.isEmpty(openTables)) {
            throw new BaseException("没有该订单,请重试");
        }
        int i = tTablenumberMapper.updateTableStatus(
                Long.valueOf(openTables.get(0).getBak1()),
                openTables.get(0).getRoomId(),
                openTables.get(0).getTableId(),
                TablenumberState.NO_LOCK.getValue(), null, null);
        if (i == 0) {
            throw new BaseException("桌子使用状态恢复失败,请重试");
        }

//        开桌会员信息
        List<TMember> members = tOpenTableMapper.getOpenTableMemberInfo(Dto.getOrderNumber());
        TIntegral tIntegrals1 = tIntegralMapper.selectCostGiveIntegral(Dto.getShopId());

        BigDecimal shiReceiveMoney = new BigDecimal(null == Dto.getShiReceiveMoney() ? "0" : Dto.getShiReceiveMoney());
        int intergrals = countGiveIntergrals(tIntegrals1, shiReceiveMoney);//计算桌子费用赠送积分
        boolean updateLogFlag = true;
        String payType = Dto.getPayType();
        for (TMember member : members) {
            Long id = member.getId();
            TMember tMember = new TMember();//修改会员对象
            tMember.setTableIng(MemberOpenTable.NO_OPEN.getValue());
            tMember.setId(id);
            tMember.setIntegral(String.valueOf(intergrals));
            Integer res1;
            if (IncomeType.MEMBERACCOUNT.getValue().equals(payType)) {//账户支付
                int moneyStatus = shiReceiveMoney.compareTo(member.getMoney());
                if (member.getMoney().intValue() <= 0 || CompareToStatus.DAYU.getValue().toString().equals(moneyStatus)) {
                    throw new BaseException(member.getName() + "账户卡金不足");
                }
                tMember.setMoney(shiReceiveMoney);
                res1 = tMemberMapper.updateMemberMoneyAndIntergralAndRecord(tMember);

            } else {
                tMember.setMoney(new BigDecimal(0.0));
                res1 = tMemberMapper.updateMemberMoneyAndIntergralAndRecord(tMember);
            }
            if (updateLogFlag) {
                //        修改 补全会员开桌时的日志 ，例如金额和积分
                TMemberLog tMemberLog2 = new TMemberLog();
                tMemberLog2.setStaffId(Dto.getStaffId());
                tMemberLog2.setIntegral(String.valueOf(intergrals));
                tMemberLog2.setMoney(Dto.getShiReceiveMoney());
                tMemberLog2.setBak1(orderNumber);
                tMemberLogService.updateTMemberLogBy0rderNumber(tMemberLog2);
                updateLogFlag = false;
            }
            //        增加会员结束开桌操作日志
  /*          TMemberLog tMemberLog = MemberLogUtil.insertMemberLog(Dto.getShopId(),
                    Dto.getStaffId(), id, String.valueOf(intergrals), Dto.getShiReceiveMoney(), "结算开桌", orderNumber, null);
            tMemberLogService.insertTMemberLog(tMemberLog);*/
//               修改流水
            TRecord record = updateTOpenTableCostRecord(
                    jbid.toString(),
                    payType,
                    CheckoutType.OK.getValue(),
                    new Date(),
                    id,
                    new Date(),
                    Dto.getStaffId().toString(),
                    orderNumber,
                    Dto.getShiReceiveMoney(),
                    Dto.getYingReceiveMoney(),
                    "1",
                    openTables.get(0).getTableId(),
                    openTables.get(0).getRoomId());
            Integer res2 = recordMapper.updateTOpenTableCostRecord(record);
            Integer res3 = recordMapper.updateTOpenTableIntergral(id, Long.valueOf(intergrals), orderNumber, openTables.get(0).getRoomId());//改变当局桌子费用赠送积分
            if (res1 == 0 || res2 == 0 || res3 == 0) {
                //  throw new BaseException("结束开桌异常,请重试");
            }
        }
//        5删除开桌中表和开桌中商品消费表的记录
        Integer status = tOpenTableMapper.deleteByOrderNumber(orderNumber);
        Integer status2 = tOpenMoneyMapper.deleteByOrderNumber(orderNumber);
        return "已结束";
    }


    private TRecord updateTOpenTableCostRecord(String jbid, String value, String value1, Date date,
                                               Long id, Date date1, String staffId, String orderNumber,
                                               String shi, String ying, String overTable,
                                               Long costTableId, Long roomId) {
        TRecord record = new TRecord();
        record.setHandoverId(jbid);
        record.setIncomeType(value);
        record.setIsCheckout(value1);
        record.setIncomeRefundTime(date);
        record.setCostMemberId(id);
        record.setUpdateTime(date1);
        record.setUpdateBy(staffId);
        record.setOrderNumber(orderNumber);
        record.setReceiveMoney(Double.valueOf(null == shi ? "0" : shi));
        record.setMoney(Double.valueOf(null == ying ? "0" : ying));
        record.setCostTable(costTableId.toString());
        record.setIncomeProjectType(roomId.toString());
        if (ObjectUtil.isNotNull(overTable)) {
            record.setOverTable(overTable);
        }
        return record;
    }

    /**
     * 根据会员消费金额计算赠送积分
     *
     * @param memberAllCostMoney 会员消费金额
     * @return
     */
    private int countGiveIntergrals(TIntegral integrals, BigDecimal memberAllCostMoney) {
        int giveIntegral = 0;

        BigDecimal costMoney = new BigDecimal(integrals.getCostMoney());
        Long i = Long.valueOf(memberAllCostMoney.compareTo(costMoney));
        if (i == CompareToStatus.DAYU.getValue()) {
            int i1 = (memberAllCostMoney.divide(costMoney)).multiply(new BigDecimal(integrals.getIntegral())).intValue();
            giveIntegral = giveIntegral + i1;

        }


        return giveIntegral;
    }

    /**
     * 取消开桌操作
     * 找出桌子开桌时间
     * 查找计费类型,再找出超时不计费的时间
     * 改变桌子状态
     * 改变流水记录
     *
     * @param orderNumber
     * @return
     */
    @Override
    @Transactional
    public String cancelOpenTable(String orderNumber) {

        List<TOpenTable> tOpenTable = tOpenTableMapper.selectTOpenTableMemberInfoByOrderNumber(orderNumber);
        if (ObjectUtil.isEmpty(tOpenTable)) {
            throw new BaseException("未查询到此桌会员信息,请重试");
        }

        String costType = tOpenTable.get(0).getCostType();
        TCost tCost = tCostMapper.selectTCostByCostType(Long.valueOf(costType));
        if (ObjectUtil.isNull(tCost)) {
            throw new BaseException("该桌计费方式可能被删除");
        }
        String startMinute = tCost.getStartMinute();//超出时间
        if (Long.valueOf(tCost.getCostUnit()) <= OpenTableCostType.XIAOSHI.getValue()) {
            Long startTime = DateUtils.parseDate(tOpenTable.get(0).getOpenStartTime()).getTime();
            String openTableTime = countOpenTableTime(startTime, null, true, false, false);
            if (Double.valueOf(openTableTime) > Double.valueOf(startMinute)) {
                return "超出规定时间不可取消开桌";
            }
        } else {
            String startTimes = tCost.getStartTime();
            int startTime = Integer.valueOf(startTimes);
            startTime = ((startTime * 60) * 60) * 1000;//毫秒值
            int hour = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
            int minute = Calendar.getInstance().get(Calendar.MINUTE);
            int nowTime = ((hour * 60) * 60) * 1000 + (minute * 60) * 1000;
            Integer outTime = ((nowTime - startTime) / 1000) / 60;
            if (outTime > Integer.valueOf(startMinute)) {
                throw new BaseException("超出规定时间不可取消开桌");
            }

        }
//        可以取消 改变桌子状态
        Integer i = tTablenumberMapper.updateTableStatus(Long.valueOf(tOpenTable.get(0).getBak1()),
                tOpenTable.get(0).getRoomId(),
                tOpenTable.get(0).getTableId(),
                TablenumberState.NO_LOCK.getValue(), null, null);
//        改变流水状态 根据订单编号
//        String  jbid  = redisCache.getCacheObject(tCost.getBak2()+tOpenTable.get(0).getStaffId().toString());
        Long jbid = redisCache.getCacheObject(tCost.getBak2() + tOpenTable.get(0).getStaffId().toString());

        TRecord tRecord = new TRecord();
        tRecord.setStaffId(Long.valueOf(tOpenTable.get(0).getStaffId()));
        tRecord.setHandoverId(jbid.toString());
        tRecord.setIsCheckout(CheckoutType.CANCEL.getValue());
        tRecord.setOrderNumber(orderNumber);
        int cancelStatus = recordMapper.updateTRecordByOrderNumber(tRecord);
        if (cancelStatus == 0) {
            throw new BaseException("取消失败请重试");
        }
//         改变会员个人开桌状态
        List<Long> memberIds = new ArrayList<>();
        for (TOpenTable openTable : tOpenTable) {
            String memberId = openTable.getMemberId();
            memberIds.add(Long.valueOf(memberId));
        }
        Long shopId = Long.valueOf(tOpenTable.get(0).getBak1());
        Integer integer = tMemberMapper.updateMemberTableIng(shopId, memberIds);
        if (integer == 0) {
            throw new BaseException("取消失败请重试");
        }

//        增加会员操作日志
      /*  for (Long memberId : memberIds) {
            TMemberLog tMemberLog = MemberLogUtil.insertMemberLog(shopId,
                    tRecord.getStaffId(), memberId, null, null, "取消开桌", orderNumber, null);
            tMemberLogService.insertTMemberLog(tMemberLog);
        }*/


//        删除开桌信息和商品消费信息
        tOpenTableMapper.deleteByOrderNumber(orderNumber);
        List<TOpenMoney> tOpenMonies = tOpenMoneyMapper.selectMemberByProductMoney(orderNumber);
        List<Long> memberId = new ArrayList<>();
        if (ObjectUtil.isNotEmpty(tOpenMonies)) {
            for (TOpenMoney mony : tOpenMonies) {
                memberId.add(mony.getMemberId());
            }
            List<String> names = tMemberMapper.selectTMembersByIdList(memberId);
            throw new BaseException(names + "购买了商品,请支付");
        }
        return "取消开桌成功";
    }

    /**
     * 更换桌号   待做是否重新计时，重新计时费用是否累加
     * 1改变原来桌号状态
     * 2改变此桌桌号
     * 3改变开桌中信息
     * 4改变流水中信息
     *
     * @param dto
     * @return
     */
    @Override
    @Synchronized
    public String changeTable(ChangeTableDto dto) {
        TTablenumber tTablenumber = tTablenumberMapper.selectTTablenumberById(dto.getNewTableId());
        TRoom tRoom = roomService.selectTRoomById(Long.valueOf(tTablenumber.getRoomType()));
//      3改变开桌中信息
        List<TOpenTable> tOpenTableList = tOpenTableMapper.selectTOpenTableMemberInfoByOrderNumber(dto.getOrderNumber());
        for (TOpenTable tOpenTable : tOpenTableList) {

            tOpenTable.setTableId(tTablenumber.getId());
            tOpenTable.setRoomType(tRoom.getRoomType());
            tOpenTable.setRoomId(tRoom.getId());
            tOpenTable.setStaffId(dto.getStaffId().toString());
            tOpenTableMapper.updateTOpenTable(tOpenTable);
        }

        TTablenumber tt = new TTablenumber();
        tt.setId(dto.getNewTableId());
        tt.setStatus("3");
        tTablenumberMapper.updateTTablenumber(tt);
        TTablenumber tablenumber = new TTablenumber();
        tablenumber.setId(dto.getTableId());
        tablenumber.setStatus("0");
        tTablenumberMapper.updateTTablenumber(tablenumber);

        DeskIng deskIng = deskIngMapper.selectByOrderSn(dto.getOrderNumber());
        deskIng.setDeskId(dto.getNewTableId());
        deskIngMapper.updateDeskIng(deskIng);
        //开关比桌子
        tablenumberService.closeEnergize(dto.getTableId());
        tablenumberService.openEnergize(dto.getNewTableId());
        return "更换成功";
    }

    @Override
    public void changeTableTime(DeskTimeDto deskTimeDto) {

        tOpenTableMapper.changeTableTime(deskTimeDto.getOpenStartTime(), deskTimeDto.getCostType(), deskTimeDto.getOrderSn());
    }

    /**
     * 暂停计时
     * 传 1 是开启暂停 0是结束暂停
     * 暂停时记录时间，结束时计算暂停时间保存到tableStop字段，下次再暂停一样的计算
     *
     * @param orderNumber
     * @return
     */
    @Override
    @Transactional
    public Integer stopTableTime(String orderNumber, String stopStatus) {


        if (stopStatus.equals("1")) {//打开暂停
            TOpenTable openTable = new TOpenTable();
            openTable.setBak2(orderNumber);
            openTable.setStopStatus(stopStatus);

            openTable.setOpenTime(String.valueOf(System.currentTimeMillis()));
            return tOpenTableMapper.updateStopStatusByorderNumber(openTable);

        }
        if (stopStatus.equals("0")) {//结束暂停
            TOpenTable tOpenTable = tOpenTableMapper.selectTOpenTableByOrderNumber(orderNumber);
            if (ObjectUtil.isNull(tOpenTable.getOpenTime())) {
                throw new BaseException("未打开暂停");
            }
            Long openTime = Long.valueOf(tOpenTable.getOpenTime());
            Long newTime = System.currentTimeMillis();
            newTime = (newTime - openTime) / 1000;

            BigDecimal stopMinute = countTime(newTime, true, false, false);
            int i = new BigDecimal(tOpenTable.getTableStop()).add(stopMinute).intValue();
            tOpenTable.setTableStop(String.valueOf(i));
            tOpenTable.setStopStatus(stopStatus);
            return tOpenTableMapper.updateStopStatusByorderNumber(tOpenTable);

        }
        throw new BaseException("暂停操作异常,请重试");
    }

    @Override
    @Transactional
    public String addPerson(String orderNumber, Long id, Long shopId, Long userId) {
        TOpenTable tOpenTable1 = tOpenTableMapper.selectTOpenTableByOrderNumber(orderNumber);
        TOpenTable tOpenTable = new TOpenTable();
        BeanUtil.copyProperties(tOpenTable1, tOpenTable);
        tOpenTable.setMemberId(id.toString());
        int i1 = tOpenTableMapper.insertTOpenTable(tOpenTable);

        //        改变会员开桌状态
        List<Long> memberIds = new ArrayList<>();
        memberIds.add(id);
        Integer i = tMemberMapper.updateMemberTableIng(shopId, memberIds);

//        添加流水日志
        Long jbid = redisCache.getCacheObject(shopId + userId.toString());
        Integer insertRecord = null;
        TRecord tRecord = new TRecord();
        tRecord.setOrderNumber(orderNumber);
        tRecord.setHandoverId(jbid.toString());
        tRecord.setStaffId(userId);
        tRecord.setShopId(shopId);
        tRecord.setIncomeProjectType(tOpenTable1.getRoomId().toString());
        tRecord.setCostTable(tOpenTable1.getTableId().toString());
        tRecord.setShopIncome(ShopIncomeType.INCOME.getValue());
        tRecord.setIsCheckout(CheckoutType.NO.getValue());
        tRecord.setCreateTime(new Date());
        tRecord.setCostMemberId(id);//消费会员
        tRecord.setBak3(tOpenTable1.getRoomId().toString());
        insertRecord = recordMapper.insertTRecord(tRecord);


       /* //                    添加日志
        TMemberLog tMemberLog = MemberLogUtil.insertMemberLog(
                shopId,
                userId,
                id,
                null,
                null,
                "加入开桌",
                orderNumber, null
        );
        int i2 = tMemberLogService.insertTMemberLog(tMemberLog);*/
        if (i1 == 0 || i == 0 || insertRecord == 0) {
            throw new BaseException("添加失败");
        }
        return "添加成功";
    }

    /**
     * 开桌会员退出，单独结账
     *
     * @return
     */
    @Override
    @Transactional
    public Integer oneOverTable(OneOverTableDto overTableDto) {
        String payType = overTableDto.getPayType();
        BigDecimal shiReceiveMoney = new BigDecimal(overTableDto.getShiReceiveMoney());
        String orderNumber = overTableDto.getOrderNumber();
        TIntegral tIntegrals1 = tIntegralMapper.selectCostGiveIntegral(overTableDto.getShopId());
        int intergrals = countGiveIntergrals(tIntegrals1, shiReceiveMoney);//计算桌子费用赠送积分

        TOpenTable tOpenTable = tOpenTableMapper.selectTOpenTableByOrderNumber(orderNumber);
        if (ObjectUtil.isNull(tOpenTable)) {
            throw new BaseException("未查到该桌台信息");
        }
        TMember tMember1 = tMemberMapper.selectTMemberById(overTableDto.getMemberId());
        Long id = tMember1.getId();
        TMember tMember = new TMember();//修改会员对象
        tMember.setTableIng(MemberOpenTable.NO_OPEN.getValue());
        tMember.setId(id);
        tMember.setIntegral(String.valueOf(intergrals));
        Integer res1;
        if (IncomeType.MEMBERACCOUNT.getValue().equals(payType)) {//账户支付
            int moneyStatus = shiReceiveMoney.compareTo(tMember1.getMoney());
            if (tMember1.getMoney().intValue() <= 0 || CompareToStatus.DAYU.getValue().toString().equals(moneyStatus)) {
                throw new BaseException(tMember1.getName() + "账户卡金不足");
            }
            tMember.setMoney(shiReceiveMoney);
            res1 = tMemberMapper.updateMemberMoneyAndIntergralAndRecord(tMember);

        } else {
            res1 = tMemberMapper.updateMemberMoneyAndIntergralAndRecord(tMember);
        }

        if (res1 == 0) {
            throw new BaseException("会员信息修改失败,请重试");
        }
        //        修改 补全会员开桌时的日志 ，例如金额和积分
        TMemberLog tMemberLog2 = new TMemberLog();
        tMemberLog2.setStaffId(overTableDto.getStaffId());
        tMemberLog2.setMemberId(id);
        tMemberLog2.setIntegral(String.valueOf(intergrals));
        tMemberLog2.setMoney(overTableDto.getShiReceiveMoney());
        tMemberLog2.setBak1(orderNumber);
        tMemberLog2.setBak2("2");
        Integer res = tMemberLogService.updateOneOverTableTMemberLogBy0rderNumber(tMemberLog2);

        //增加会员中途结束开桌操作日志
        TMemberLog tMemberLog = MemberLogUtil.insertMemberLog(
                overTableDto.getShopId(),
                overTableDto.getStaffId(),
                id,
                String.valueOf(intergrals),
                null,
                null,
                overTableDto.getShiReceiveMoney(),
                MemberLogType.XF.getValue(),
                orderNumber,
                "2",
                tMember.getMoney()
        );
        int i = tMemberLogService.insertTMemberLog(tMemberLog);
       /* if (res == 0 || i == 0) {
            throw new BaseException("会员日志更改失败,请重试");
        }*/
        Long jbid = redisCache.getCacheObject(overTableDto.getShopId() + overTableDto.getStaffId().toString());

        //               修改流水
        TRecord record = updateTOpenTableCostRecord(
                jbid.toString(),
                payType,
                CheckoutType.OK.getValue(),
                new Date(),
                id,
                new Date(),
                overTableDto.getStaffId().toString(),
                orderNumber,
                overTableDto.getShiReceiveMoney(),
                overTableDto.getYingReceiveMoney(),
                "2",
                tOpenTable.getTableId(),
                tOpenTable.getRoomId());
        Integer res2 = recordMapper.updateOneOverTOpenTableCostRecord(record);
        Long roomId = tOpenTable.getRoomId();
        Integer res3 = recordMapper.updateTOpenTableIntergral(id, Long.valueOf(intergrals), orderNumber, roomId);//改变当局桌子费用赠送积分
        if (res2 == 0 || res3 == 0) {
            throw new BaseException("流水记录更新失败,请重试");
        }
        //        5删除开桌中表和开桌中商品消费表的记录
        Integer status = tOpenTableMapper.deleteByOrderNumberAndMemberId(orderNumber, id);
        Integer status2 = tOpenMoneyMapper.deleteByOrderNumberAndMemberId(orderNumber, id);
        return null;
    }

    @Override
    public Integer updateRemark(String orderNumber, String remark) {
        return tOpenMoneyMapper.updateRemark(orderNumber, remark);
    }

    /**
     * 开桌后新增会员信息
     *
     * @param memberId
     * @param orderNumber
     */
    @Override
    public void addMember(Long memberId, String orderNumber) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        TMember tMember = tMemberMapper.selectTMemberById(memberId);
        /* List<TOpenTable> openTableList = tOpenTableMapper.selectTOpenTableMemberInfoByOrderNumber(orderNumber);*/
        DeskIng ing = deskIngMapper.selectByOrderSn(orderNumber);
        TTablenumber tTablenumber = tTablenumberMapper.selectTTablenumberById(ing.getDeskId());
        List<TOpenTable> openTableList = tOpenTableMapper.selectTOpenTableMemberInfoByOrderNumber(orderNumber);

        String date = ObjectUtils.isEmpty(openTableList) ? DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, ing.getStartTime()) : openTableList.get(0).getOpenStartTime();
      /*  if (ObjectUtil.isNotNull(openTableList)) {
            if (openTableList.size() != 0) {*/
        TOpenTable tOpenTable = new TOpenTable();
        tOpenTable.setId(null);
        tOpenTable.setCostType(ing.getMode());
        tOpenTable.setBak1(ing.getShopId().toString());
        if (null != ing.getDeskNumber()) {
            tOpenTable.setRoomId(Long.valueOf(ing.getDeskNumber()));
        }

        tOpenTable.setTableId(ing.getDeskId());
        tOpenTable.setMemberId(tMember.getId().toString());
        tOpenTable.setMemberName(tMember.getName());
        tOpenTable.setOpenStartTime(date);
        tOpenTable.setOpenTime(null);
        tOpenTable.setRoomId(Long.valueOf(tTablenumber.getRoomType()));
        tOpenTable.setStaffId(user.getUserId().toString());
        tOpenTable.setBak2(orderNumber);
        tOpenTable.setBak3(null);
        tOpenTable.setMoney(new BigDecimal("0.0"));
        tOpenTableMapper.insertTOpenTable(tOpenTable);
    }


    /**
     * 开桌后删除会员
     *
     * @param deskMemberDto
     */
    @Override
    public void deleteByMemberId(DeskMemberDto deskMemberDto) {

        tOpenTableMapper.updateIsDel(deskMemberDto.getOrderNumber(), deskMemberDto.getMemberId());
        TMember member = new TMember();
        member.setId(deskMemberDto.getMemberId());
        member.setTableIng(0L);
        member.setStatus(DeskStatusEnum.OK_REFUND.getValue());
        tMemberMapper.updateTMember(member);
    }

    @Override
    public List<DeskVo> selectTabels(TOpenTable table1) {
        List<DeskVo> deskVoList = tOpenTableMapper.selectTabels(table1);
       /* for (DeskVo vo : deskVoList) {

            vo.setOpenTime(DateUtils.countOpenTableTime(Long.valueOf((null==vo.getOpenTime()?null:vo.getOpenTime())), null, false, false, false));
        }*/
        return deskVoList;
    }

    @Override
    public void changeRemark(ChangDto changDto) {
        tOpenTableMapper.updateReamrk(changDto.getRemark(), changDto.getOrderSn());
    }

    /**
     * 单人结算
     *
     * @param memberId
     * @param deskId
     */
    @Override
    public void checkout(Long memberId, Long deskId) {
        TOpenTable tOpenTable = tOpenTableMapper.selectOne(deskId, memberId);
        if (DeskStatusEnum.OK_REFUND.getValue().equals(tOpenTable.getStatus())) {
            throw new RuntimeException("已完成结账操作！");
        }
        calculateService.calculate(tOpenTable);
    }

    /**
     * 多人结算
     *
     * @param deskId
     */
    @Override
    public void checkoutAll(Long deskId) {
        List<TOpenTable> openTableList = tOpenTableMapper.selectTOpenTableMemberInfoByOrderNumber(deskId.toString());
        if (ObjectUtil.isNotEmpty(openTableList)) {
            for (TOpenTable tOpenTable : openTableList) {
                calculateService.calCommidtyPrice(tOpenTable);
            }
        }

    }

    /**
     * 暂定计时功能
     *
     * @param suspendDto
     */
    @Override
    public void suspend(SuspendDto suspendDto) {
        SysUser user = SecurityUtils.getLoginUser().getUser();
        Long shopId = redisCache.getCacheObject(Constants.SHOP_SUF + user.getUserId());
        SysDept dept = sysDeptService.selectDeptById(shopId);
        //email未临时使用的暂停密码
        String checkPassword = dept.getEmail();
        if (!checkPassword.equals(suspendDto.getPassWord())) {
            throw new RuntimeException("密码错误，请重新输入");
        }
        List<TOpenTable> openTableList = tOpenTableMapper.selectTOpenTableMemberInfoByOrderNumber(suspendDto.getDeskId().toString());
        Long tableId = 0L;
        if (ObjectUtil.isNotEmpty(openTableList)) {
            tableId = openTableList.get(0).getTableId();
        }

        if (suspendDto.getStatus().equals(StopStatus.END_STOP.getValue())) {
            for (TOpenTable tOpenTable : openTableList) {
                tOpenTable.setStopStatus(StopStatus.END_STOP.getValue());
                updateTOpenTable(tOpenTable);
            }
            //桌子断电
            tablenumberService.closeEnergize(tableId);
        } else {
            for (TOpenTable tOpenTable : openTableList) {
                tOpenTable.setStopStatus(StopStatus.START_STOP.getValue());
                updateTOpenTable(tOpenTable);
            }
            //桌子通电
            tablenumberService.openEnergize(tableId);
        }


    }

    @Override
    @Transactional
    public AjaxResult coverDesk(Long deskIngId) {
        List<TOpenTable> openTableList = tOpenTableMapper.selectTOpenTableMemberInfoByOrderNumber(deskIngId.toString());
        for (TOpenTable table : openTableList) {
            if (!DeskStatusEnum.OK_REFUND.getValue().equals(table.getStatus())) {
                //开桌费用
                BigDecimal deskmoney = table.getMoney();
                //商品费用
                List<TOpenMoney> tOpenMonies = tOpenMoneyMapper.selectTOpenMoneyBymemberId(table.getMemberId(), table.getBak2());
                double proMoneyStr = tOpenMonies.stream().mapToDouble(obj -> obj.getMoney().doubleValue()).sum();
                BigDecimal proMoney = new BigDecimal(proMoneyStr);
                //计算出扣除的总额
                BigDecimal money = deskmoney.add(proMoney);
                TMember member = tMemberMapper.selectTMemberById(Long.valueOf(table.getMemberId()));
                if (member.getMoney().compareTo(money) < 0) {
                    return AjaxResult.error("结账失败，用户【" + member.getName() + "】卡内余额不足，请进行充值");
                }
                // 卡内余额
                BigDecimal memberMoney = member.getMoney();
                member.setMoney(member.getMoney().subtract(money));
                tMemberMapper.updateTMember(member);
                SysUser user = SecurityUtils.getLoginUser().getUser();
                Long shopId = redisCache.getCacheObject(Constants.SHOP_SUF + user.getUserId());
                calculateService.saveLog(shopId, user, member, money, deskmoney, proMoney, table);
                // 保存会员日志
//                TMemberLog tMemberLog = MemberLogUtil.insertMemberLog(
//                        shopId, user.getUserId(), member.getId(), null, null, null,
//                        money.toString(), MemberLogType.XF.getValue() ,
//                        "开桌费:" + deskmoney + ",商品消费:" + proMoney + ",余额:" + memberMoney,
//                        table.getRemark(), memberMoney
//                );
//                tMemberLogService.insertTMemberLog(tMemberLog);
            }
        }
        TOpenTable openTable = tOpenTableMapper.selectTOpenTableByOrderNumber(deskIngId.toString());
//        openTable.setStatus(YesORNoEnum.NO.getValue().toString());
//        openTable.setUpdateTime(new Date());
//        tOpenTableMapper.updateTOpenTable(openTable);
        if (null != openTable) {
            TTablenumber tTablenumber = new TTablenumber();
            tTablenumber.setStatus(TablenumberState.NO_LOCK.getValue());
            tTablenumber.setId(openTable.getTableId());
            tTablenumberMapper.updateTTablenumber(tTablenumber);
        }else {
            DeskIng deskIng = deskIngMapper.selectByOrderSn(deskIngId.toString());
            TTablenumber tTablenumber = new TTablenumber();
            tTablenumber.setStatus(TablenumberState.NO_LOCK.getValue());
            tTablenumber.setId(deskIng.getDeskId());
            tTablenumberMapper.updateTTablenumber(tTablenumber);
        }
//        tablenumberService.closeEnergize(openTable.getTableId());
        return AjaxResult.success("结账成功");
    }

    @Override
    public void tmpStopDesk(String orderSn) {
        tTablenumberMapper.tmpStopDesk(orderSn);
    }

    @Override
    public Long updateStatus(String orderSn) {

        return tOpenTableMapper.updateStatus(orderSn);
    }


    /**
     * 计算费用方法
     *
     * @param orderNumber =订单编号
     * @param startTime   = 开始时间/毫秒值
     * @return
     */
    private BigDecimal countOpenTableCost(String orderNumber, Long startTime) {
        TOpenTable tOpenTable = tOpenTableMapper.selectTOpenTableByOrderNumber(orderNumber);
        BigDecimal stopTime = new BigDecimal(tOpenTable.getTableStop());
        TCost tCost = tCostMapper.selectTCostByCostType(Long.valueOf(tOpenTable.getCostType()));
        BigDecimal money = new BigDecimal(tCost.getMoney());
        //       使用分钟
        String useMinute = countOpenTableTime(startTime, stopTime, true, false, false);
        //       使用小时
//        String  useHour =countOpenTableTime(startTime,null,false,true,false);

//        String costUnit = tCost.getCostUnit();


//         按分钟计费分支 1.使用多少分钟 2.每分钟多少钱 3.各种意外收费(例如超时收费)
        int i = useMinute.indexOf(".");
        if (i == -1) {//不带小数点，代表整数，直接计算
            return new BigDecimal(useMinute).multiply(money);
        }

//            计算带小数点的分钟
        int indexOf = useMinute.indexOf(".");
        BigDecimal finalMoney = new BigDecimal(useMinute.substring(0, indexOf)).multiply(money).setScale(2, BigDecimal.ROUND_HALF_UP);
        String s = "0." + useMinute.substring(indexOf + 1);
//            此桌使用费用
        finalMoney = finalMoney.add(new BigDecimal(tOpenTable.getBak3())).setScale(2, BigDecimal.ROUND_HALF_UP);
//           返回费用
        return finalMoney.add(new BigDecimal(s).multiply(money).setScale(2, BigDecimal.ROUND_HALF_UP));


//        if (costUnit.equals(CostUnit.HOUR.getValue())){
////            按照小时计费分支  ,1 使用多少小时,每小时多少钱,各种意外收费
//            int i = useHour.indexOf(".");
//            if (i==-1){//不带小数点，代表整数，直接计算
//                return  new BigDecimal(useMinute).multiply(money);
//            }
//        }
//        throw  new BaseException("计算费用异常,请重试");
    }

    /**
     * 计算开桌时间
     * minuteFlag=只查询分钟
     * hours=只查询小时
     * 默认查询使用时间字符串
     *
     * @param startTimeMinute=开局时间
     * @return
     */
    private String countOpenTableTime(long startTimeMinute, BigDecimal stopTime, Boolean minuteFlag, Boolean hours, Boolean day) {
        Long newTime = new Date().getTime();
        long miao = (newTime - startTimeMinute) / 1000;//秒
//        计算时间
        BigDecimal minute = countTime(miao, true, false, false);
        if (stopTime != null) {//计算暂停时间
            minute = minute.subtract(stopTime);
        }

        BigDecimal hour = countTime(miao, false, true, false);
        if (stopTime != null) {//计算暂停时间
            hour = (hour.multiply(new BigDecimal(60))).subtract(stopTime);
        }
        BigDecimal days = countTime(miao, false, false, true);

        if (minuteFlag) {
            return minute.toString();
        }
        if (hours) {
            return hour.toString();
        }
        if (day) {
            return day.toString();
        }

        String useTime = "";//时间字符串
        if (!String.valueOf(hour).equals("0.0") || Double.valueOf(hour.toString()) >= 1.0) {
            useTime = hour + "小时";
        }
        if (!String.valueOf(minute).equals("0.0") || Double.valueOf(minute.toString()) >= 1.0) {
            useTime = useTime + minute + "分钟";
        }
        Long useHours = miao / 3600;
        Long useMinutes = (miao % 3600) / 60;
        useTime = useHours + "小时" + useMinutes + "分钟";
        return useTime;
    }

    /**
     * 计算分钟和小时和天 精确到秒数向上取整 例如 70秒=1.2分钟
     *
     * @param miao
     * @return
     */
    private BigDecimal countTime(long miao, Boolean minute, Boolean hour, Boolean day) {

        if (minute) {//秒转分
            BigDecimal minutes = new BigDecimal(miao).divide(new BigDecimal(60), 2, BigDecimal.ROUND_UP).setScale(1, BigDecimal.ROUND_HALF_UP);
            return minutes;
        }
        if (hour) {//分转时
            BigDecimal minutses = new BigDecimal(miao).divide(new BigDecimal(60), 2, BigDecimal.ROUND_UP).setScale(1, BigDecimal.ROUND_HALF_UP);
            return minutses.divide(new BigDecimal(60), 2, BigDecimal.ROUND_UP).setScale(1, BigDecimal.ROUND_HALF_UP);
        }
        //时转天
        BigDecimal minutses = new BigDecimal(miao).divide(new BigDecimal(60), 2, BigDecimal.ROUND_UP).setScale(1, BigDecimal.ROUND_HALF_UP);
        BigDecimal hours = minutses.divide(new BigDecimal(60), 2, BigDecimal.ROUND_UP).setScale(1, BigDecimal.ROUND_HALF_UP);
        return hours.divide(new BigDecimal(24), 2, BigDecimal.ROUND_UP).setScale(1, BigDecimal.ROUND_HALF_UP);
    }


    /**
     * 查询当前员工归属店面id和所有归属店面所有员工信息
     * key =当前员工归属店面id
     * value =归属店面所有员工信息
     * belong=店面id
     *
     * @return
     */
    private Map<String, List<SysUser>> getStaffList(Long staffId) {
        Map<String, List<SysUser>> map = new HashMap<>();
        List<SysUser> sysUser = userMapper.selectUserBelongById(staffId);
        String belong = null;
        for (SysUser user : sysUser) {
            if (user.getUserId() == staffId) {
                belong = user.getBelong();
            }
        }
        map.put(belong, sysUser);
        return map;
    }
}
//            按照时间收费判断是否满足断电
//            if (costUnitFlag){
//                 allMoney = money.add(memberProductMoney);//用于判断是否满足断电
//                int i = member.getMoney().compareTo(allMoney);//是否满足断电状态
//                if (i==-1){
//                    tOpenTableVo.setAccountStatus("2");
//                }
//            }else { //按照段收费判断
//              int i=  member.getMoney().compareTo(  bak3.add(memberProductMoney));
//               if(i==-1){
//                   tOpenTableVo.setAccountStatus("2");
//               }
//            }
////            按照包段收费判断是否满足断电
////             String bak3 = tOpenTables.get(0).getBak3();
//             BigDecimal add = new BigDecimal(bak3).add(memberProductMoney);
//            int i = member.getMoney().compareTo(add);//是否满足断电状态
//             if (i==-1){
//                 tOpenTableVo.setAccountStatus("2");
//             }else { //按照段收费判断
//                 int i2=  member.getMoney().compareTo(  bak3.add(memberProductMoney));
//                 if(i2==-1){
//                     tOpenTableVo.setAc
